<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>Colors</title>
</head>

<body onload="initWebGL()">
	<canvas id="my-canvas" width="500" height="500">
    </canvas>
</body>
<script src="libs/gl-matrix-min.js"></script>
<script src="libs/jquery.min.js"></script>
<script src="libs/webgl-utils.js"></script>
<script id="shader-vs" type="shader">
	attribute vec3 aVertexPosition;
	attribute vec4 aVertexColor;
	
	uniform mat4 uPMatrix;
	uniform mat4 uMVMatrix;
	
	varying vec4 vColor;
	
	void main(void){
		gl_Position = uPMatrix * uMVMatrix * vec4(aVertexPosition, 1.0);
		vColor = aVertexColor;
	}
</script>
<script id="shader-fs" type="shader">
	precision mediump float;
	varying vec4 vColor;
	
	void main(void){
		gl_FragColor = vColor;
	}
</script>
<script>
	var gl = null,
		program = null,
		width = 0,
		height = 0;
	
	var triangleVertexPositionBuffer;
	var triangleVertexColorBuffer;
	var squareVertexPositionBuffer;
	var squareVertexColorBuffer;
		
	var mvMatrix = mat4.create(),
		pMatrix = mat4.create();
	
	var rTri = 0;
	var rSquare = 0;
	var mvMatrixStack = [];
	
	function mvPushMatrix(){
		var copy = mat4.create();
		mat4.set(mvMatrix, copy);
		mvMatrixStack.push(copy);
	}
	
	function mvPopMatrix(){
		if (mvMatrixStack.length == 0){
			throw "Invalid popMatrix!";
		}
		mvMatrix = mvMatrixStack.pop();
	}
	
	function initProgram(){
		var vertexShader = makeShader(document.getElementById("shader-vs").innerHTML, gl.VERTEX_SHADER);
		var fragmentShader = makeShader(document.getElementById("shader-fs").innerHTML, gl.FRAGMENT_SHADER);
		
		program = gl.createProgram();
		gl.attachShader(program, vertexShader);
		gl.attachShader(program, fragmentShader);;
		gl.linkProgram(program);
		gl.useProgram(program);
		
		program.vertexPositionAttribute = gl.getAttribLocation(program, "aVertexPosition");
		gl.enableVertexAttribArray(program.vertexPositionAttribute);
		program.vertexColorAttribute = gl.getAttribLocation(program, "aVertexColor");
		gl.enableVertexAttribArray(program.vertexColorAttribute);
		
		getMatrixUniforms();
	}
	
	function getMatrixUniforms(){
		program.mvMatrixUniform = gl.getUniformLocation(program, "uMVMatrix");
		program.pMatrixUniform = gl.getUniformLocation(program, "uPMatrix");
	}
	
	function setMatrixUniforms(){
		gl.uniformMatrix4fv(program.mvMatrixUniform, false, mvMatrix);
		gl.uniformMatrix4fv(program.pMatrixUniform, false, pMatrix);
	}
	
	function makeShader(src, type){
		var shader = gl.createShader(type);
		gl.shaderSource(shader, src);
		gl.compileShader(shader);
		return shader;
	}
	
	function setupBuffers(){
		var vertices = [
             0.0,  1.0,  0.0,
            -1.0, -1.0,  0.0,
             1.0, -1.0,  0.0
        ];
		triangleVertexPositionBuffer = gl.createBuffer();
		gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexPositionBuffer);
		gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
		triangleVertexPositionBuffer.itemSize = 3;
		triangleVertexPositionBuffer.numItems = 3;
		
		var colors = [
            1.0, 0.0, 0.0, 1.0,
            0.0, 1.0, 0.0, 1.0,
            0.0, 0.0, 1.0, 1.0
        ];
		triangleVertexColorBuffer = gl.createBuffer();
		gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexColorBuffer);
		gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
		triangleVertexColorBuffer.itemSize = 4;
		triangleVertexColorBuffer.numItems = 3;
		
		vertices = [
             1.0,  1.0,  0.0,
            -1.0,  1.0,  0.0,
             1.0, -1.0,  0.0,
            -1.0, -1.0,  0.0
        ];
		colors = [];
        for (var i=0; i < 4; i++) {
            colors = colors.concat([0.5, 0.5, 1.0, 1.0]);
        }
		squareVertexPositionBuffer = gl.createBuffer();
		gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexPositionBuffer);
		gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(vertices), gl.STATIC_DRAW);
		squareVertexPositionBuffer.itemSize = 3;
		squareVertexPositionBuffer.numItems = 4;
		
		squareVertexColorBuffer = gl.createBuffer();
		gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexColorBuffer);
		gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(colors), gl.STATIC_DRAW);
		squareVertexColorBuffer.itemSize = 4;
		squareVertexColorBuffer.numItems = 4;
	}
	
	function setupWebGL(){
		gl.viewport(0, 0, width, height);
		gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
	}
	
	function drawScene(){
		setupWebGL();
		
		mat4.perspective(45, width / height, 0.1, 100.0, pMatrix);
		mat4.identity(mvMatrix);
		mat4.translate(mvMatrix, [-1.5, 0.0, -7.0]);
		
		mvPushMatrix();
		mat4.rotate(mvMatrix, rTri * Math.PI / 180.0, [0,1,0]);
		
		gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexPositionBuffer);
		gl.vertexAttribPointer(program.vertexPositionAttribute, triangleVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
		
		gl.bindBuffer(gl.ARRAY_BUFFER, triangleVertexColorBuffer);
		gl.vertexAttribPointer(program.vertexColorAttribute, triangleVertexColorBuffer.itemSize, gl.FLOAT, false, 0, 0);
		
		setMatrixUniforms();
		gl.drawArrays(gl.TRIANGLES, 0, triangleVertexPositionBuffer.numItems);
		mvPopMatrix();
		
		mat4.translate(mvMatrix, [3.0, 0.0, 0.0]);
		
		mvPushMatrix();
		mat4.rotate(mvMatrix, rSquare * Math.PI / 180.0, [1, 0, 0]);
		
		gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexPositionBuffer);
		gl.vertexAttribPointer(program.vertexPositionAttribute, squareVertexPositionBuffer.itemSize, gl.FLOAT, false, 0, 0);
		
		gl.bindBuffer(gl.ARRAY_BUFFER, squareVertexColorBuffer);
		gl.vertexAttribPointer(program.vertexColorAttribute, squareVertexColorBuffer.itemSize, gl.FLOAT, false, 0, 0);
		
		setMatrixUniforms();
		gl.drawArrays(gl.TRIANGLE_STRIP, 0, squareVertexPositionBuffer.numItems);
		
		mvPopMatrix();
	}
	
	function renderLoop(){
		requestAnimFrame(renderLoop);
		drawScene();
		animate();
	}
	
	var lastTime = 0;
	
	function animate(){
		var timeNow = new Date().getTime();
		if (lastTime != 0){
			var elapsed = timeNow - lastTime;
			
			rTri += (90 * elapsed) / 1000.0;
			rSquare += (75*elapsed) / 1000.0;
		}
		lastTime = timeNow;
	}
	
	function initWebGL(){
		var canvas = document.getElementById("my-canvas");
		width = canvas.width;
		height = canvas.height;
		try
		{
			gl = canvas.getContext("webgl") || canvas.getContext("experimental-webgl");
		}
		catch (e){ }
		if (gl){
			initProgram();
			setupBuffers();
			
			gl.clearColor(0.0, 0.0, 0.0, 1.0);
			gl.enable(gl.DEPTH_TEST);
			renderLoop();
		} else {
			alert('no sp');
		}
	}
</script>
</html>
